<?php
App::uses('AppController', 'Controller');
/**
 * Stories Controller
 *
 * @property Story $Story
 * @property PaginatorComponent $Paginator
 */
class StoriesController extends AppController {

/**
 * Components
 *
 * @var array
 */
	public $components = array('Paginator');

/**
 * index method
 *
 * @return void
 */
	public function index() {
		$this->Story->recursive = 0;
		$this->set('stories', $this->Paginator->paginate());
	}

/**
 * view method
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */
	public function view($id = null) {
		if (!$this->Story->exists($id)) {
			throw new NotFoundException(__('Invalid story'));
		}
		$options = array('conditions' => array('Story.' . $this->Story->primaryKey => $id));
		$this->set('story', $this->Story->find('first', $options));
	}

/**
 * add method
 *
 * @return void
 */
	public function add() {
	
		//TODO - Get uid from Session.
		$uid = 7;
		if ($this->request->is('post')) {
			$this->Story->create();
			$this->Story->set($this->request->data);
			$this->Story->set(array('status' => StoriesController::STORY_STATUS_PENDING_ITEMS,
									'user_id'=> $uid));
			if ($this->Story->save()) {
				$this->Session->setFlash(__('The story has been saved.'));
				return $this->redirect(array('controller' 	=> 'StoryItems', 
										  	 'action' 		=> 'add',
										  	 'action' 		=> 'add',
											 $this->Story->id)); //pass story id to add items function
			} else {
				$this->Session->setFlash(__('The story could not be saved. Please, try again.'));
			}
		}
		$users = $this->Story->User->find('list');
		$this->set(compact('users'));
	}

/**
 * edit method
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */
	public function edit($id = null) {
		if (!$this->Story->exists($id)) {
			throw new NotFoundException(__('Invalid story'));
		}
		if ($this->request->is(array('post', 'put'))) {
			if ($this->Story->save($this->request->data)) {
				$this->Session->setFlash(__('The story has been saved.'));
				return $this->redirect(array('action' => 'index'));
			} else {
				$this->Session->setFlash(__('The story could not be saved. Please, try again.'));
			}
		} else {
			$options = array('conditions' => array('Story.' . $this->Story->primaryKey => $id));
			$this->request->data = $this->Story->find('first', $options);
		}
		$users = $this->Story->User->find('list');
		$this->set(compact('users'));
	}

/**
 * delete method
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */
	public function delete($id = null) {
		$this->Story->id = $id;
		if (!$this->Story->exists()) {
			throw new NotFoundException(__('Invalid story'));
		}
		$this->request->onlyAllow('post', 'delete');
		if ($this->Story->delete()) {
			$this->Session->setFlash(__('The story has been deleted.'));
		} else {
			$this->Session->setFlash(__('The story could not be deleted. Please, try again.'));
		}
		return $this->redirect(array('action' => 'index'));
	}

	/**
 * Check if story's status needs to be changed, and return new state
 *
 * @throws NotFoundException
 * @param string $id
 * @return int
 */	
	private function calcStorysNewStatusAfterCheck($story_id){
		$validCount = 0;
		$fakeCount = 0;
		
		//Count Verdicts
		$responses = $this->Story->CheckerResponse->find('all', array('conditions' => array('CheckerResponse.story_id' => $story_id)));
		
		foreach($responses as $response){
			if ($response['CheckerResponse']['verdict'] == true){
				$validCount++;
			} else {
				$fakeCount++;
			}
		}
		
		$status = StoriesController::STORY_STATUS_NEW;
		
		if ($validCount >= StoriesController::STORY_CR_FOR_BEING_VALID){
			$status = StoriesController::STORY_STATUS_CHECKED;
		}
		
		if ($fakeCount >= StoriesController::STORY_CR_FOR_BEING_INVALID){
			$status = StoriesController::STORY_STATUS_FAKE;
		}
		
		return $status;
	}
	
	public function approve($story_id = null, $note = null){
		$this->request->onlyAllow('post', 'approve');
		
		$this->Story->id = $story_id;
		if (!$this->Story->exists()){
			throw new NotFoundException(__('Invalid story'));
		}
		
		//TODO - Get uid from Session
		$uid = 1;
		
		$this->approverWork($uid, $story_id, true, $note);
		$this->redirect(array('action' => 'index'));
	}
	
	public function approverWork($user_id, $story_id, $verdict, $note){
		//can approve only in validation status
		if (!$this->isStoryInStatus($story_id, StoriesController::STORY_STATUS_IN_VALIDATION)){
			$this->Session->setFlash(StoriesController::STORY_MESSAGES_NOT_IN_VALIDATION_STATUS);
			return;
		}
		$this->Story->ApproverResponse->create();
		$this->Story->ApproverResponse->save(array('user_id' => $user_id, 'story_id' => $story_id, 'verdict' => $verdict, 'note' => $note), false);
		
		$status = $verdict ? StoriesController::STORY_STATUS_APPROVED : StoriesController::STORY_STATUS_FAKE;
		$this->changeStatus($story_id, $status);
		$msg = $verdict ? StoriesController::STORY_MESSAGES_APPROVED : StoriesController::STORY_MESSAGES_DISAPPROVED;
		$this->Session->setFlash($msg);
	}
	
	public function disapprove($story_id = null, $note = null){
		$this->request->onlyAllow('post', 'disapprove');
		
		$this->Story->id = $story_id;
		if (!$this->Story->exists()){
			throw new NotFoundException(__('Invalid story'));
		}
		
		//TODO - Get uid from Session
		$uid = 1;
		
		$this->approverWork($uid, $story_id, false, $note);
		$this->redirect(array('action' => 'index'));
	}
		
/**
 * Check story to valid be valid
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */	
	public function checkValid($story_id = null) {
		$this->request->onlyAllow('post', 'check');
		
		$this->Story->id = $story_id;
		if (!$this->Story->exists()){
			throw new NotFoundException(__('Invalid story'));
		}
		
		//TODO - Get user id form session
		$this->validation(3, $story_id, true);
		
		return $this->redirect(array('action' => 'index'));	
}

/**
 * Check story to valid be valid
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */	
	public function checkInvalid($story_id = null) {
		$this->request->onlyAllow('post', 'check');
		
		$this->Story->id = $story_id;
		if (!$this->Story->exists()){
			throw new NotFoundException(__('Invalid story'));
		}
		
		//TODO - Get user id form session
		$this->validation(1, $story_id, false);
		
		return $this->redirect(array('action' => 'index'));	
}

/**
 * Set story validation
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */	
	private function validation($uid, $story_id, $verdict){
		$story = $this->Story->find('first', array('conditions' => array('Story.id' => $story_id)));
		if (!$this->isStoryInStatus($story_id, StoriesController::STORY_STATUS_NEW)){
			$this->Session->setFlash(StoriesController::STORY_MESSAGES_ALREADY_DONE_CHECKING);
			return;
		}
		
		$cr = $this->Story->CheckerResponse->find('first', array('conditions' => array('CheckerResponse.user_id' => $uid)));
		if (!empty($cr)){
			$this->Session->setFlash(StoriesController::STORY_MESSAGES_USER_ALREADY_CHECKED_STORY);
			return;
		}

		//Add checker response
		$this->Story->CheckerResponse->create();
		$this->Story->CheckerResponse->save(array('user_id' => $uid, 'story_id' => $story_id, 'verdict' => $verdict), false);
		
		$status = $this->calcStorysNewStatusAfterCheck($story_id);
		if ($status != StoriesController::STORY_STATUS_NEW){
			$this->changeStatus($story_id, $status);
		}
		
		if ($verdict){
			$this->Session->setFlash(__(StoriesController::STORY_MESSAGES_VALIDATED));
		} else {
			$this->Session->setFlash(__(StoriesController::STORY_MESSAGES_INVALIDATED));	
		}
	}

/**
 * return true if story is wanted status
 *
 * @throws NotFoundException
 * @param string $id
 * @return bool
 */	
	private function isStoryInStatus($story_id, $wantedStatus){
		$story = $this->Story->find('first', array('conditions' => array('Story.id' => $story_id)));
		return $story['Story']['status'] == $wantedStatus;
	}
	
/**
 * Changes the status of the story
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */
	private function changeStatus($id = null, $status){
		$this->Story->id = $id;
		if (!$this->Story->exists()) {
			throw new NotFoundException(__('Invalid story'));
		}
		$this->Story->set('status', $status);
		$this->Story->save();
	}
	
	//Story Status
	const STORY_STATUS_PENDING_ITEMS 		= 1;
	const STORY_STATUS_PENDING_APPROVAL 	= 2;
	const STORY_STATUS_PUBLISHED			= 3;
	const STORY_STATUS_DONE					= 4;
	const STORY_STATUS_EXPIRED				= 5;
		
	const STORY_MESSAGES_USER_ALREADY_CHECKED_STORY		= "You have already checked this story.";
	const STORY_MESSAGES_STORY_CHECKED_MAX_TIMES		= "Story is already checked";
	const STORY_MESSAGES_ALREADY_DONE_CHECKING			= "Story passed checking stage...";
	const STORY_MESSAGES_VALIDATED 						= "Story has been validated.";
	const STORY_MESSAGES_INVALIDATED 					= "Story has been invalidated.";
	const STORY_MESSAGES_APPROVED 						= "Story has been Approved.";
	const STORY_MESSAGES_DISAPPROVED 					= "Story has been Dispproved.";
	const STORY_MESSAGES_NOT_IN_VALIDATION_STATUS		= "Story is not in \"Validation\" Status.";
	
	const STORY_MAX_CR_COUNT 							= 3;
	const STORY_CR_FOR_BEING_VALID 						= 2;
	const STORY_CR_FOR_BEING_INVALID					= 2;
}
